const chalk = require('chalk')
const defconfig = require('../config');
const axios = require('axios');
const path = require('path');
const fs = require('fs-extra');
const $RefParser = require('json-schema-ref-parser');
const  OpenAI = require('openai')
async function fetchRemoteOpenApi(url) {
  try {
    // 使用 axios 发起 GET 请求
    const response = await axios.get(url);
    // response.data 包含了请求返回的数据，即 OpenAPI 文件内容
    return response.data;
  } catch (error) {
    // 错误处理
    console.error('读取远程 OpenAPI 文件时出错');
    throw error;
  }
}

const generateColumns = (model,config) => {
  const columns = {};
  let cstr=''
  const groups={};

  function builder(key,field){
    const column = {
      title: field.description,
      type: field.type === 'string' ? 'text' : (field.type === 'integer' ? 'number' : field.type)
    };
    //let extend=''
    // Special handling for specific fields
    if (field.format === 'date-time') {
      column.type = 'datetime';
      //extend=',valueBuilder:useCrudDayBuilder,valueResolve:useCrudDayResolve';
    }
    
    // cstr+=`"${key}": { title: "${column.title}", type: "${column.type}"${extend} },
    //           `
    columns[key] = column;
  }

  Object.keys(model).forEach(key => {
    const field = model[key];
    if(config.omitKey.includes(key)) return;
    if(field.type=='object'&&field.properties){
      const newgroup={
        tab: field.description,
        columns:[]
      }
      Object.keys(field.properties).forEach(key2 => {
        if(config.omitKey.includes(key2)) return;
        builder(key+'.'+key2,field.properties[key2])
        newgroup.columns.push(key+'.'+key2)
      })
      groups[key] = newgroup;
    }else{  
      builder(key,field)
    }
    
  });
  // console.log(JSON.stringify(columns))
  return {cstr,columns,groups};
};

function generateString(columns){
  // let cstr=''
  let search= false
  for (const key in columns) {
    const field = columns[key];
    if(field.hasOwnProperty('search'))search=true;
    if (field.format === 'datetime') {
      // extend=',valueBuilder:useCrudDayBuilder,valueResolve:useCrudDayResolve';
      field.valueBuilder='useCrudDayBuilder'
      field.valueResolve='useCrudDayResolve'
    }
    if(['editor-wang5'].includes(field.type)){
      field.form = field.form || {}
      field.form.col = field.form.col || {}
      field.form.col.span = 24
    }
  }
  let cstr = JSON.stringify(columns);
  cstr=cstr.split('"useCrudDayBuilder"').join('useCrudDayBuilder')
  cstr=cstr.split('"useCrudDayResolve"').join('useCrudDayResolve')
  return {model:cstr,search}
}



module.exports = async function createPage(str, options){
  // console.log(str)
  try {
    const config = Object.assign({omitKey:[]}, defconfig, str);
    if(!config.openapiUrl)return console.log(chalk.red.bold('openapi地址为空'));
    let data = await fetchRemoteOpenApi(config.openapiUrl)
    data = await $RefParser.dereference(data);
    const apipath =  config.modelUrl.replace(/\/[^\/]*$/, '')
    const file= config.path|| apipath
    const savePath = path.join(process.cwd(), config.pagePath||'pages',file+'.vue')
    // 按照路径合并接口项目
    const fullPath =config.cutPath+config.modelUrl
    let schema
    for (const key in data.paths) {
      if(key ==fullPath ) {
        for (const key2 in data.paths[key]) {
          //console.log(data.paths[key][key2]["requestBody"]["content"]["application/json"]["schema"])
          if(data.paths[key][key2]["requestBody"]["content"]["application/json"]["schema"]["properties"]) {
            schema=data.paths[key][key2]["requestBody"]["content"]["application/json"]["schema"]["properties"]
          }
        }
      }
    }

    let {columns,groups} = generateColumns(schema,config)
    //是否用AI优化模型
    if(config.useAi&&config.ai_Key&&config.ai_words){
      const openai = new OpenAI({
        baseURL: config.ai_URL,
        apiKey:  config.ai_Key
      });
      config.ai_words.push(config.aiWord)
      const completion = await openai.chat.completions.create({
        messages: [
          {
            role: "system",
            content: "You are a helpful assistant designed to output JSON.返回压缩成一行的json字符串",
          },
          {
            role: "system",
            content: config.ai_words.join('||'),
          },
          { role: "user", content: JSON.stringify(columns) },
        ],
        model: config.ai_model||"gpt-4o",
        response_format: { type: "json_object" },
      });
      columns=JSON.parse(completion.choices[0].message.content)
    }

    const {model,search} = generateString(columns)
    
    let groupstr=''
    if(Object.keys(groups).length !== 0){
      groupstr=`
        group:{
          groupType: "tabs", //or tabs
          accordion: false, //手风琴模式
          groups:${JSON.stringify(groups)}
        },
        `
    }

    const search_str = search?'':'search: { show: false },'
    let drawer_str=''
    if(config.drawer){
      drawer_str=`wrapper: {
        is: "a-drawer",
        onClosed(e) {},
        onOpened(e) {},
      },`
    }


    const fileContext = `
    <script lang="ts" setup>
    import * as API from '@/api/method/${apipath}';
    import { type CreateCrudOptionsRet, useFs,dict } from "@fast-crud/fast-crud";
    //此处为crudOptions配置
    const createCrudOptions = function (): CreateCrudOptionsRet {
       return {
          crudOptions: {
             request: useCrud(API),
             // rowHandle:{show:false},
            ${search_str}
            // actionbar: { show: false },
             toolbar: { show: false },
             rowHandle: {fixed: "right"},
             form: {
              ${groupstr}
              ${drawer_str}
              labelCol: {
                //固定label宽度
                span: null,
                style: {
                  width: "100px",
                },
              },
             },
             columns: ${model}
          }
       };
    };
    
    const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions, context: {} });
    onMounted(() => {
       crudExpose.doRefresh();
    });
    
    </script>
    <template>
       <div class="bg-white b-rd-10px p-20px m-20px" style="height: calc(100vh - 103px);">
       <!-- <AppTitle>标题</AppTitle> -->
          <fs-crud ref="crudRef" v-bind="crudBinding" />
       </div>
    </template>
    `
    await fs.outputFile(savePath, fileContext)
    console.log(chalk.green.bold('生成完成'));
  } catch (error) {
    console.log(chalk.red.bold('解析失败'),error);
  }
 
}